package com.training.service;

import com.training.entity.User; // Import User entity
import com.training.mapper.UserMapper; // Import UserMapper
import org.springframework.beans.factory.annotation.Autowired; // Import Autowired annotation
import org.springframework.stereotype.Service; // Import Service annotation
import org.springframework.transaction.annotation.Transactional; // Import Transactional annotation

import java.util.List; // Import List collection

@Service // Mark this as a Service class
public class UserService {

    private final UserMapper userMapper; // Declare UserMapper as final

    @Autowired // Auto-inject UserMapper instance via constructor
    public UserService(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    /**
     * Get list of all non-logically deleted users.
     * @return List of User objects
     */
    public List<User> getAllUsers() {
        // Assuming userMapper.findAll() returns non-deleted users or you need to add a filter
        return userMapper.findAll();
    }

    /**
     * Save a new user. This method is now primarily used for initial creation.
     * After insertion, if useGeneratedKeys and keyProperty are configured in XML,
     * the 'id' field of the user object will be automatically populated with the database-generated ID.
     *
     * @param user User object to save
     * @return The saved User object (with ID populated)
     */
    public User saveUser(User user) {
        // If using password encryption: user.setPassword(passwordEncoder.encode(user.getPassword()));
        // For now, assuming plain text as per your original code.
        userMapper.insert(user);
        return user;
    }

    /**
     * Authenticate a user by username and password.
     * @param username User's username
     * @param password User's password
     * @return User object if authentication is successful, null otherwise
     */
    public User authenticateUser(String username, String password) {
        User user = userMapper.findByUsername(username); // First, find user by username

        // --- IMPORTANT: Add this debug print line ---
        System.out.println("UserService - Authenticating user: " + username + ", retrieved user object: " + user);
        // --- End of debug print ---

        if (user != null && user.getDeleted() == 0) { // Check if user exists and is not logically deleted
            // !!! DANGER: Plain text password comparison. FOR DEMO ONLY.
            // In production, use a strong password hashing mechanism (e.g., BCryptPasswordEncoder).
            if (user.getPassword().equals(password)) { // Compare stored password with provided password
                return user; // Passwords match, return the user object
            }
        }
        return null; // User not found, logically deleted, or password does not match
    }

    /**
     * Find a user by username.
     * @param username 用户名
     * @return 用户对象，如果找不到返回 null
     */
    public User findByUsername(String username) {
        return userMapper.findByUsername(username);
    }

    /**
     * NEW: Register a new user account.
     * This method checks for duplicate usernames before saving.
     *
     * @param user The User object to register (username, password, role)
     * @return The newly created User object with its ID, or null if username already exists.
     */
    @Transactional // Ensure atomicity for user creation
    public User registerUser(User user) {
        // Check if username already exists
        if (userMapper.findByUsername(user.getUsername()) != null) {
            System.err.println("注册失败：用户名 '" + user.getUsername() + "' 已存在。");
            return null; // Username already exists
        }

        // Set default values for new user
        user.setDeleted(0); // Default to not deleted
        // If you have createTime/updateTime fields in User entity, set them here
        // user.setCreateTime(new Timestamp(System.currentTimeMillis()));
        // user.setUpdateTime(new Timestamp(System.currentTimeMillis()));

        // Save the user (password hashing should ideally happen here or in a dedicated encoder)
        // For now, keeping it as plain text as per your original code, but strongly recommend hashing.
        userMapper.insert(user); // This will populate user.id if configured in mapper XML
        return user;
    }

    /**
     * NEW: Update an existing user's information.
     * This method checks for duplicate usernames (excluding the current user's own username).
     *
     * @param user The User object with updated information (id, username, password, role)
     * @return true if update is successful, false otherwise (e.g., username already exists for another user)
     */
    @Transactional // Ensure atomicity for user update
    public boolean updateUser(User user) {
        // Check if the new username already exists for another user
        User existingUserWithSameUsername = userMapper.findByUsername(user.getUsername());
        if (existingUserWithSameUsername != null && !existingUserWithSameUsername.getId().equals(user.getId())) {
            System.err.println("更新失败：用户名 '" + user.getUsername() + "' 已被其他用户占用。");
            return false; // Username already exists for a different user
        }

        // If password is provided, it should be hashed before updating.
        // For now, directly setting it as per your original code.
        // if (user.getPassword() != null && !user.getPassword().isEmpty()) {
        //    user.setPassword(passwordEncoder.encode(user.getPassword()));
        // } else {
        //    // If password is empty, retrieve existing password to prevent overwriting with null/empty
        //    User existingUser = userMapper.findById(user.getId());
        //    if (existingUser != null) {
        //        user.setPassword(existingUser.getPassword());
        //    }
        // }

        // Set update time if applicable
        // user.setUpdateTime(new Timestamp(System.currentTimeMillis()));

        int affectedRows = userMapper.updateUser(user); // Assuming you have an updateUser method in UserMapper
        return affectedRows > 0;
    }

    /**
     * NEW: Find a user by ID.
     * @param id User ID
     * @return User object if found and not logically deleted, null otherwise
     */
    public User getUserById(Long id) {
        User user = userMapper.findById(id); // Assuming you have findById method in UserMapper
        // Only return if not logically deleted
        return (user != null && user.getDeleted() == 0) ? user : null;
    }

    /**
     * NEW: Logically delete a user by ID.
     * Sets the 'deleted' flag to 1.
     * @param id User ID to delete
     * @return true if deletion is successful, false otherwise
     */
    @Transactional // Ensure atomicity for user deletion
    public boolean deleteUser(Long id) {
        int affectedRows = userMapper.deleteUser(id); // Assuming you have a deleteUser method in UserMapper
        return affectedRows > 0;
    }
}
